#include "mainwindow.h"
#include "ui_TryAndBuyExample.h"
#include "buycatalog.h"
#include "DRMFile.h"

#include <QtGui/QPushButton>
#include <QtGui/QLabel>
#include <QtGui/QMessageBox>
#include <QtCore/QDirIterator>
#include <QtCore/QDebug>
#include <QtGui/QApplication>
#include <QTimer>
#include <QProgressDialog>

#define TICKETFOLDERNAME "tickets"

/*
 *
 */
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    gameLevels(NULL),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    catalog = new BuyCatalog(this);
    connect(ui->exitButton, SIGNAL(clicked()), this, SLOT(mainWindowClose()));
    connect(ui->resetButton, SIGNAL(clicked()), this, SLOT(mainWindowResetPurchases()));
}

/*
 *
 */
MainWindow::~MainWindow()
{
    delete catalog;
    delete gameLevels;
    delete ui;
}

/*
 *
 */
void MainWindow::playLevel()
{
    // which button triggered this action and what is the content of the corresponding label (file name)
    QObject* object ;
    QString levelName;
    foreach(object, sender()->parent()->children())
    {
        if(QString::compare(object->metaObject()->className(),"QLabel",Qt::CaseSensitive) == 0)
        {
            levelName = ((QLabel*)object)->text();
            break;
        }
    }

    // find the full path for that file name
    QStringList list = gameLevels->filter(levelName, Qt::CaseSensitive);
    if(list.count()>0)
    {
        // try to access it
        DRMFile file;
        int error = file.open(list[0]);
        if(isPurchased(error, list[0]))
        {
            // if you can, "play" the level
            uchar* buffer = NULL;
            int len = file.read(buffer);
            if(len>0)
            {
                QMessageBox msgBox;
                msgBox.setText(QString().fromAscii((const char*)buffer, len - 2)); //cut off CRLF
                msgBox.exec();
            }
            delete buffer;
            file.close();
        }
        else
        {
            file.close();
            // opening failed due to DRM protection?
            // start In-Application Purchase experience
            QString product = getProductId(list[0]);
            catalog->setDefaultProduct(product);
            catalog->showFullScreen();
        }
    }
}

/*
 *
 */
void MainWindow::listLevels(const QString& path)
{
    qDebug() << "Processing: " << path;

    ui->listWidget->clear();

    if(gameLevels==NULL)
    {
        gameLevels = new QStringList();

        QStringList filters;
        filters << "level*.dat";

        QDirIterator dirit(path, filters, QDir::NoFilter, QDirIterator::Subdirectories);
        while(dirit.hasNext())
                gameLevels->append(dirit.next());

        //gameLevels->sort();
    }

    if(gameLevels->count()==0)
    {
        QMessageBox mb;
        mb.setText(tr("No files found."));
        mb.exec();
    }

    for (int i = 0; i<gameLevels->count(); i++)
    {
        QString fileName = gameLevels->at(i);

        QStringList pathItems = fileName.split("/",QString::SkipEmptyParts,Qt::CaseInsensitive);

        QListWidgetItem *item = new QListWidgetItem();
        ui->listWidget->addItem(item);
        QPushButton *button = new QPushButton();
        button->setWhatsThis(fileName);

        DRMFile file;
        int error = file.open(fileName);
        if(isPurchased(error, fileName))
            button->setText(tr("Play"));
        else
            button->setText(tr("Unlock"));
        file.close();

        button->setStyleSheet(QString::fromUtf8("QPushButton{ background-color: rgb(0, 0, 255); border-style: outset; border-width: 2px; border-radius: 10px; border-color: beige; font: bold 14px; min-width: 4em; max-width: 5em; padding: 6px; } QPushButton:pressed { background-color: rgb(100, 100, 250); border-style: inset;}"));

        qDebug() << "File " << fileName << "is set as" << button->text() << ".";

        QLabel *label = new QLabel(pathItems.last());
        QHBoxLayout *layout= new QHBoxLayout();
        layout->addWidget(label);
        layout->addWidget(button);
        QWidget *widget = new QWidget();
        widget->setLayout(layout);
        item->setSizeHint(widget->sizeHint());
        ui->listWidget->setItemWidget(item, widget);
        connect(button, SIGNAL(clicked()), this, SLOT(playLevel()));
    }
}

void MainWindow::updateLevels()
{
    for (int i = 0; i<gameLevels->count(); i++)
    {
        QString fileName = gameLevels->at(i);
        QPushButton *button = getButton(fileName);
        if(!button)
            continue;

        DRMFile file;
        int error = file.open(fileName);
        if(isPurchased(error, fileName))
            button->setText(tr("Play"));
        else
            button->setText(tr("Unlock"));
        file.close();
    }
}

QPushButton *MainWindow::getButton(QString& fname)
{
    for(int i = 0; i < ui->listWidget->count(); i++)
    {
        QListWidgetItem* item = ui->listWidget->item(i);
        QWidget* widget = ui->listWidget->itemWidget(item);
        foreach(QObject* object, widget->children())
        {
            QWidget *child = qobject_cast<QWidget*>(object);
            if(!child)
                continue;

            if(QString::compare(child->whatsThis(), fname) == 0)
            {
                return qobject_cast<QPushButton*>(object);
            }
        }
    }
    return NULL;
}

/*
 *
 */
void MainWindow::catalogClosed()
{
    updateLevels();
}

void MainWindow::mainWindowClose()
{
    close();
}

void MainWindow::mainWindowResetPurchases()
{
    QString dirName = getTicketDir();
    QDir dir(dirName);

    if(!dir.exists(dirName))
        return;

    bool result;
    foreach(QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot |
                                              QDir::System |
                                              QDir::Hidden  |
                                              QDir::AllDirs |
                                              QDir::Files,
                                              QDir::DirsFirst))
    {
        result = QFile::remove(info.absoluteFilePath());
        if (!result)
        {
            break;
        }
    }
    dir.rmdir(dirName);
    updateLevels();
}

bool MainWindow::isPurchased(int drmErrCode, QString& fileName)
{
    QString drmPath(QApplication::applicationDirPath());
    drmPath.append("/drm");
    if(fileName.startsWith(drmPath))
    {
        QString productID = getProductId(fileName);
        return (drmErrCode == KErrNone && readTicket(productID));
    }
    else
    {
        return true;
    }
}

QString MainWindow::getProductId(const QString& path)
{
    // breakdown the !:/private/<SID>/drm/data/resourceid_<productID>/file.ext
    // extract the product to which this file belongs
    QStringList elem = path.split("_", QString::SkipEmptyParts);
    elem=elem[1].split("/", QString::SkipEmptyParts);
    return (elem[0]);
}

void MainWindow::saveTicket(const QString& purchaseTicket, QString& productID)
{
    if (purchaseTicket.isEmpty() || productID.isEmpty())
        return;

    QString privatedir(getTicketDir());
    if (!QDir(privatedir).exists())
        QDir().mkdir(privatedir);

    QFile file(getTicketUri(productID));
    if (file.open(QIODevice::WriteOnly)){
        QDataStream out(&file);
        out << purchaseTicket;
        file.close();
    }
    else
    {
        qDebug() << "MainWindow::testModeSaveTicket >>> Cannot open file for writing: ";
    }

    productID = "";
}

bool MainWindow::readTicket(const QString& productID)
{
    return (QFile(getTicketUri(productID)).exists());
}

QString MainWindow::getTicketUri(const QString& productID)
{
    QString fname(QApplication::applicationDirPath());
    fname.append("/");
    fname.append(TICKETFOLDERNAME);
    fname.append("/");
    fname.append(productID);
    fname.append(".ticket");
    return fname;
}

QString MainWindow::getTicketDir()
{
    QString fname(QApplication::applicationDirPath());
    fname.append("/");
    fname.append(TICKETFOLDERNAME);
    return fname;
}

